﻿using System;
using System.Collections.Generic;
using System.Threading;
using Skynet.CommonLibrary.ThreadQueue.Interface;

namespace Skynet.CommonLibrary.ThreadQueue.Pool
{
    /// <summary>
    /// 接收数据池
    /// </summary>
    /// <typeparam name="T">数据类型</typeparam>
    ///<remarks>
    /// 作者：         李志强
    /// 开发时间：  2011-04-18
    /// </remarks>
   internal class ReceiveDataPool<T> : IDataPool<T>
    {
        readonly Queue<T> _queue;
        readonly IComponent _center;
        static readonly ReaderWriterLock RwLock = new ReaderWriterLock();
        const int LockTimeOut = 10000;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="maxSize">队列中最大长度</param>
        /// <param name="center">操作组件</param>
        internal ReceiveDataPool(int maxSize, IComponent center)
        {
            MaxSize = maxSize;
            _queue = new Queue<T>();
            _center = center;
        }

        /// <summary>
        /// 缓冲区最大容量
        /// </summary>
      public  int MaxSize
        {
            get;
            private set;
        }

        /// <summary>
        /// 缓冲区数量
        /// </summary>
        /// <returns></returns>
      public int Count
        {
            get { return _queue.Count; }
        }

        /// <summary>
        /// 返回最顶端的数据，如果没有数据则返回NULL
        /// </summary>
        /// <returns></returns>
      public T Dequeue()
      {
          try
          {
              RwLock.AcquireReaderLock(LockTimeOut);
              //if (Count > 0)
              //{
                  T entity = _queue.Dequeue();
                  if (DequeueAction != null)
                  {
                      DequeueAction(entity);
                  }
                  return entity;
              //}
          }
          catch { }
          finally 
          {
              if (RwLock.IsReaderLockHeld)
              {
                  RwLock.ReleaseReaderLock();
              }
          }
          return default(T);
      }

        /// <summary>
        /// 添加数据到队列中，如果队列数量大于所设置的最大容量则抛出异常
        /// </summary>
        /// <param name="o"></param>
        public void Enqueue(T o)
        {
            if (Count >= MaxSize)
            {
                throw new Exception("超出缓冲区大小");
            }
            if (o == null)
                return;
               
            try
            {
                RwLock.AcquireWriterLock(LockTimeOut);
                _queue.Enqueue(o);

                if (EnqueueAction != null)
                {
                    EnqueueAction(o);
                }
            }
            finally
            { RwLock.ReleaseWriterLock(); }
            _center.Operation(null);
        }


        //入队列和出队列通知委托
        public Action<T> EnqueueAction { private get; set; }
        public Action<T> DequeueAction { private get; set; }
    }
}
